package com.lanou3g.ptp.attendance.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lanou3g.ptp.attendance.mapper.AttendanceMapper;
import com.lanou3g.ptp.attendance.service.AttendanceService;
import com.lanou3g.ptp.entity.Attendance;
import com.lanou3g.ptp.entity.SignInDate;
import com.lanou3g.ptp.entity.Task;
import com.lanou3g.ptp.signInDate.service.SignInDateService;
import com.lanou3g.ptp.task.service.TaskService;
import com.lanou3g.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PathVariable;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class AttendanceServiceImpl implements AttendanceService {

    @Reference
    private SignInDateService signInDateService;

    @Autowired
    private AttendanceMapper attendanceMapper;

    @Reference
    private TaskService taskService;

    @Autowired
    private AttendanceService attendanceService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Value("${REDIS_ATTEBDANCE_KEY_PREFIX}")
    private String REDIS_ATTEBDANCE_KEY_PREFIX;

    @Override
    public void addAttentInfor(Attendance attendance) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date signTime = attendance.getSignTime();
        String attentTime = sdf.format(signTime);
        System.out.println(signTime);
        System.out.println(sdf.format(signTime));
        Long taskId = attendance.getTaskId();
        Long studentId = attendance.getStudentId();
        if (isTodayInSignInDates(taskId)) {
            /*
            firstLat firstLong 用户坐标经纬度
            secondLat secondLong 打卡任务经纬度
            radius 打卡范围
             */
            double firstLat = Double.parseDouble(attendance.getLatitude());
            double firstLong = Double.parseDouble(attendance.getLongitude());
            Task task = taskService.findById(taskId);
            double secondLat = Double.parseDouble(task.getLatitude());
            double secondLong = Double.parseDouble(task.getLongitude());
            Integer radius = task.getRadius();
            if (getDistance(firstLat, firstLong, secondLat, secondLong) <= radius) {
                String s = REDIS_ATTEBDANCE_KEY_PREFIX + studentId + "-" + taskId + "-" + attentTime;
                String s1 = JSON.toJSONString(signTime);
                redisTemplate.opsForList().rightPush(s,s1);
            } else {
                System.out.println("请移动到指定范围内打卡,谢谢");
            }
        } else {
            System.out.println("二货,请在任务规定日期内签到");
        }
    }

    @Override
    public List<List<Date>> findByAttentTime(Long studentId, Long taskId
            ,Date startTime, Date endTime){
        List<String> days = getDays(startTime, endTime);
        List<List<Date>> objects = new ArrayList<>();
        for (String day : days) {
            List<Date> object1 = new ArrayList<>();
            String s = REDIS_ATTEBDANCE_KEY_PREFIX + studentId + "-" + taskId + "-" + day;
            List<String> range = redisTemplate.opsForList().range(s, 0, -1);
            if (range.size()==0){
                object1.add(null);
            }else {
                for (String s1 : range) {
                    Date date = new Date(Long.parseLong(s1));
                    object1.add(date);
                }
            }
            objects.add(object1);
        }
        System.out.println(objects);
        return objects;

    }

    private List<String> getDays(Date startTime,Date endTime) {

        // 返回的日期集合
        List<String> days = new ArrayList<String>();

        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Calendar tempStart = Calendar.getInstance();
            tempStart.setTime(startTime);

            Calendar tempEnd = Calendar.getInstance();
            tempEnd.setTime(endTime);
            tempEnd.add(Calendar.DATE, +1);// 日期加1(包含结束)
            while (tempStart.before(tempEnd)) {
                days.add(dateFormat.format(tempStart.getTime()));
                tempStart.add(Calendar.DAY_OF_YEAR, 1);
            }
        return days;
    }



    private boolean isTodayInSignInDates(Long taskId) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String today = sdf.format(new Date());
        List<SignInDate> signTime = signInDateService.findSignTime(taskId);
        for (SignInDate signInDate : signTime) {
            if (sdf.format(signInDate.getDate()).equals(today)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<Attendance> findByStudentId(long studentId) {
        List<Attendance> byStudentId = attendanceMapper.findByStudentId(studentId);
        return byStudentId;
    }

    @Override
    public List<Attendance> findByStudentIdAndDate(long studentId, Date startDate, Date overDate) {
        List<Attendance> attendances = attendanceMapper.findByStudentIdAndDate(studentId,startDate,overDate);
        return attendances;
    }

    @Override
    public PageInfo<Attendance> findAll(Integer page, Integer size) {
        PageHelper.startPage(page, size);
        List<Attendance> all = attendanceMapper.findAll();
        return new PageInfo<>(all);
    }

    @Override
    public List<Attendance> findAll1() {
        List<Attendance> all1 = attendanceMapper.findAll1();
        return all1;
    }

    /**
     * 计算两个坐标点之间的距离
     *
     * @param firstLatitude  第一个坐标的纬度
     * @param firstLongitude 第一个坐标的经度
     * @param secondLatitude 第二个坐标的纬度
     * @param secondLatitude 第二个坐标的经度
     */

    private double getDistance(double firstLatitude, double firstLongitude,
                               double secondLatitude, double secondLongitude) {

        double a = 111 * Math.cos(Math.toRadians(firstLatitude))
                - 111 * Math.cos(Math.toRadians(secondLatitude));

        double b = 111 * (firstLongitude - secondLongitude);
        double result = Math.sqrt(a * a + b * b);
        return result * 1000;
    }

    @Override
    public void updateByStudentId(long studentId, Attendance attendance) {
        attendanceMapper.updateByStudentId(studentId, attendance);
    }

    @Override
    public void deleteByStudentId(long studentId) {
        attendanceMapper.deleteByStudentId(studentId);
    }

    @Override
    public List<Attendance> findSignTime(long studentId, String signTime) {

        List<Attendance> list = attendanceMapper.findSignTime(studentId, signTime);
        return list;
    }

    @Override
    public List<Attendance> findStudentTask(long studentId, long taskId) {

        return attendanceMapper.findStudentTask(studentId, taskId);
    }

    @Override
    public List<Attendance> findByTaskId(long taskId) {
        List<Attendance> byTaskId = attendanceMapper.findByTaskId(taskId);
        return byTaskId;
    }

    @Override
    public Integer findByDate(Long studentId,Date startDate, Date endDate) {
        Integer integer = attendanceMapper.findByDate(studentId,startDate,endDate);
        return integer;
    }

    @Override
    public List<Attendance> findByDateId(Date startDate,Date endDate) {
        List<Attendance> attendances = attendanceMapper.findByDateId(startDate,endDate);
        return attendances;
    }


}
